home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / mips / mipsdepend.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  10.7 KB  |  338 lines

  1. functor MipsInstr(structure E:ENDIAN) : MACHINSTR =
  2. struct
  3.  
  4. structure M = MipsInstrSet
  5. open M
  6.  
  7. val branchDelayedArch = true
  8.  
  9. datatype ikind = IK_NOP | IK_JUMP | IK_INSTR
  10.  
  11. val error = ErrorMsg.impossible
  12.  
  13. fun instrKind instr = case instr
  14.                 of M.NOP     => IK_NOP
  15.                  | M.JUMP _  => IK_JUMP
  16.              | M.BEQ _   => IK_JUMP
  17.              | M.BCOP1 _ => IK_JUMP
  18.              | _         => IK_INSTR
  19.  
  20. fun isSdiBranch (BRANCH _) = true
  21.   | isSdiBranch (BRANCH_COP1 _) = true
  22.   | isSdiBranch _ = false
  23.  
  24. val nop = M.NOP
  25.  
  26. fun minSize (LOADF _) = 8
  27.   | minSize _           = 4
  28.  
  29.  
  30. (* sizeOf(sdi,loc) 
  31.  *    returns the size of I under the current address assignment
  32.  * for labels plus true if the size if the maximum possible for the sdi. 
  33.  *)
  34. fun sizeOf (info as INFO{addrOf,...}) =
  35.  let val labelValue = M.labelValue info
  36.      val hiLabelValue = M.hiLabelValue info
  37.      val loLabelValue = M.loLabelValue info
  38.   in fn (sdi,loc) =>
  39.   let 
  40.     fun lab_value (lab,k) = labelValue(POSLAB lab,k -  M.constBaseRegOffset)
  41.     fun is_short_mem n = ~32764 <= n andalso n <= 32764
  42.     fun is_short_branch lab = let 
  43.         val const = addrOf lab - (loc + 4)
  44.       in 
  45.       is_short_mem(const div 4)
  46.       end
  47.   in
  48.       case sdi 
  49.       of SETBASEADDR(lab,reg) => let
  50.        val const = M.constBaseRegOffset - (addrOf lab)
  51.      in 
  52.          if is_short_mem const then (false, 4) else (true, 12)
  53.      end
  54.       | LOADADDR(_,lab,k)  =>
  55.       if is_short_mem (lab_value (lab,k)) then (false,4) else (true,12) 
  56.       | LOAD(_,lab,k) =>
  57.       if is_short_mem (lab_value (lab,k)) then (false,4) else (true,12) 
  58.       | LOADF(_,lab,offset,_)  => let
  59.       val labexp1 = (POSLAB lab,offset-M.constBaseRegOffset)
  60.       val labexp2 = (POSLAB lab,offset-M.constBaseRegOffset+4)
  61.       val labval1 = labelValue labexp1
  62.       val labval2 = labelValue labexp2
  63.         in
  64.       if (is_short_mem labval1) andalso (is_short_mem labval2) 
  65.       then (false, 8)
  66.       else if (hiLabelValue labexp1) = (hiLabelValue labexp2)
  67.            then (false,16)
  68.            else (true,20)
  69.         end
  70.       | BRANCH(_,_,_,lab,_,_) =>
  71.       if is_short_branch lab then (false,4) else (true,20)
  72.       | BRANCH_COP1(_,lab,_,_) =>
  73.       if is_short_branch lab then (false,4) else (true,20)
  74.   end
  75.  end
  76.  
  77. (* expand (I, n)
  78.  *    - expands I into n bytes of machine instructions. 
  79.  *)
  80. fun expand info (sdi,size,loc) =
  81.     case sdi
  82.     of SETBASEADDR(lab,reg) =>
  83.       let val labexp = (NEGLAB lab,M.constBaseRegOffset)
  84.       in
  85.         case size 
  86.         of 4 => [M.ADD(M.baseReg,reg,LabelOp labexp)]
  87.          | 12 => [M.LUI(M.baseReg,HiLabOff labexp),
  88.               M.ADD(M.baseReg,M.baseReg,LoLabOp labexp),
  89.               M.ADD(M.baseReg,reg,RegOp M.baseReg)]
  90.          | _ => error "MipsInstrSet.expand: SETBASEADDR"
  91.       end
  92.      | LOADADDR(r,lab,k) =>
  93.        let val labexp = (POSLAB lab,~M.constBaseRegOffset+k)
  94.        in case size
  95.           of 4 => [M.ADD(r,M.baseReg,LabelOp labexp)]
  96.            | 12 =>  [M.LUI(r,HiLabOff labexp),
  97.              M.ADD(r,r,LoLabOp labexp),
  98.              M.ADD(r,M.baseReg,RegOp r)]
  99.            | _ => error "MipsInstrSet.expand: LOADADDR"
  100.        end
  101.      | LOAD(r,lab,k) =>
  102.        let val labexp = (POSLAB lab,~M.constBaseRegOffset+k)
  103.        in case size
  104.           of 4  => [M.LW(r,M.baseReg,LabOff labexp)]
  105.            | 12 => [M.LUI(r,HiLabOff labexp),
  106.             M.ADD(r,M.baseReg,RegOp r),
  107.             M.LW(r,r,LoLabOff labexp)]
  108.            | _ => error "MipsInstrSet.expand: LOAD"
  109.        end
  110.      | LOADF(fp',lab,offset,tmpR) => 
  111.        let val Freg' fp = reg_rep fp'
  112.            val labexp1 = (POSLAB lab,offset-M.constBaseRegOffset)
  113.            val labexp2 = (POSLAB lab,offset-M.constBaseRegOffset+4)
  114.            val lowOff = E.low_order_offset
  115.        in case size 
  116.           of 8 => 
  117.              [M.LWC1(Freg(fp+lowOff),M.baseReg,LabOff labexp1),
  118.               M.LWC1(Freg(fp+1-lowOff),M.baseReg,LabOff labexp2)]
  119.            | 16 => 
  120.              [M.LUI(tmpR,HiLabOff labexp1),
  121.               M.ADD(tmpR,tmpR,RegOp M.baseReg),
  122.               M.LWC1(Freg(fp+lowOff),tmpR,LoLabOff labexp1),
  123.               M.LWC1(Freg(fp+1-lowOff),tmpR,LoLabOff labexp2)]
  124.            | 20 => 
  125.              [M.LUI(tmpR,HiLabOff labexp1),
  126.               M.ADD(tmpR,tmpR,LoLabOp labexp1),
  127.               M.ADD(tmpR,tmpR,RegOp M.baseReg),
  128.               M.LWC1(Freg(fp+lowOff),tmpR,Immed16Off 0),
  129.               M.LWC1(Freg(fp+1-lowOff),tmpR,Immed16Off 4)]
  130.            | _ => error "MipsInstrSet.expand: LOADF"
  131.        end
  132.      | BRANCH(bool,rs,rt,tlabel,tmpR,flabel) => 
  133.        (case size
  134.         of 4  => [M.BEQ(bool,rs,rt,LabOff(POSLAB tlabel,0))]
  135.  
  136.         | 20 => 
  137.           let val labexp = (POSLAB tlabel,~M.constBaseRegOffset)
  138.           in
  139.               [M.BEQ(not bool,rs,rt,LabOff(POSLAB flabel,0)),
  140.  
  141.                M.LUI(tmpR,HiLabOff labexp),
  142.                M.ADD(tmpR,tmpR,LoLabOp labexp),
  143.                M.ADD(tmpR,tmpR,RegOp M.baseReg),
  144.                M.JUMP(tmpR)]
  145.           end
  146.        | _ => error "MipsInstrSet.expand: BRANCH")
  147.      | BRANCH_COP1(bool,tlabel,tmpR,flabel) => 
  148.        (case size 
  149.             of 4  => [M.BCOP1(bool,LabOff(POSLAB tlabel,0))]
  150.              | 20 => 
  151.           let val labexp = (POSLAB tlabel,~M.constBaseRegOffset)
  152.           in
  153.               [M.BCOP1(not bool,LabOff(POSLAB flabel,0)),
  154.  
  155.                M.LUI(tmpR,HiLabOff labexp),
  156.                M.ADD(tmpR,tmpR,LoLabOp labexp),
  157.                M.ADD(tmpR,tmpR,RegOp M.baseReg),
  158.                M.JUMP(tmpR)]
  159.           end
  160.          | _ => error "MipsInstrSet.expand: BRANCH_COP1")
  161.  
  162. (* 
  163.  * Resources:  Mem+($1-$31)+($f0,f1-$f31)+fcc+npc+LO+HI 
  164.  *)
  165. val numResources     = 68
  166.  
  167. local
  168.     structure RId = 
  169.     struct
  170.         val mem = 0
  171.         fun reg r = case reg_rep r 
  172.                  of Reg' 0 => []
  173.               | Reg' i => [i]
  174.               | _ => error "MipsInstrSet.RId.reg"
  175.         fun freg r = case reg_rep r 
  176.                  of Freg' i => [32+i]
  177.               | _ => error "MipsInstrSet.RId.freg"
  178.         fun fregd r = case reg_rep r 
  179.                  of Freg' i => [32+i, 32+1+i]
  180.               | _ => error "MipsInstrSet.RId.fregd"
  181.         fun anyreg r = case reg_rep r 
  182.         of Reg' 0 => []
  183.          | Reg' i => [i]
  184.          | Freg' i => [32+i]
  185.         val fcc = 64 
  186.         val npc = 65 
  187.         val LO  = 66 
  188.         val HI  = 67 
  189.         
  190.         val Reg'(alloc)  = reg_rep M.allocReg (* resource no. for reg = reg no. *)
  191.         val Reg'(exnptr) = reg_rep M.exnptrReg
  192.     end
  193.  
  194.     fun is_allocR reg = reg_eq(reg,M.allocReg)
  195.     fun arithOpndUse opnd = case opnd of RegOp r => RId.reg r | _ => []
  196.  
  197.     val allR = let fun f(~1,l) = l | f(i,l) = f(i-1,i::l)
  198.            in f(numResources-1,[])
  199.            end
  200.     local
  201.     open RId
  202.     in
  203.         fun arith_ud(rd,rs,ea)    = (exnptr::(reg rs @ arithOpndUse ea), reg rd)
  204.     fun logical_ud(rd,rs,ea)  = (reg rs @ arithOpndUse ea, reg rd)
  205.     fun arith3_ud(rd,rt,rs)   = (exnptr::(reg rt @ reg rs), reg rd)
  206.     fun logical3_ud(rd,rt,rs) = (reg rs @ reg rt, reg rd)
  207.  
  208.         fun double_float_ud(fd,fs,ft)  
  209.                               = (exnptr::(fregd fs @ fregd ft), fregd fd)
  210.  
  211.     fun mult_ud(rt,rs)        = (reg rs @ reg rt, [LO,HI])
  212.  
  213.     fun load_ud(rt,base,_)    = (mem::npc::anyreg base,anyreg rt)
  214.     fun store_ud(rt,base,_)   = let val use = anyreg rt @ anyreg base
  215.                     in if is_allocR base then (use, []) 
  216.                        else (use,[mem])
  217.                     end
  218.     end
  219. in
  220.  
  221.   fun rUseDef inst =
  222.       case inst 
  223.       of M.NOP            => ([], [])
  224.  
  225.        | M.BEQ(_,rt,rs,_) => (RId.reg rs @ RId.reg rt,   [RId.npc])
  226.        | M.JUMP rs        => (RId.reg rs,              [RId.npc])
  227.        | M.BCOP1 _        => ([RId.fcc],              [RId.npc])
  228.        | M.BLTZAL ()      => (allR,                  allR)
  229.        | M.BREAK _        => (allR,             allR)
  230.  
  231.        | M.SLT arg           => logical_ud arg
  232.        | M.SLTU arg         => logical_ud arg
  233.        | M.SLT_DOUBLE(rt,rs) => (RId.fregd rt @ RId.fregd rs, [RId.fcc])
  234.        | M.SEQ_DOUBLE(rt,rs) => (RId.fregd rt @ RId.fregd rs, [RId.fcc])
  235.  
  236.        | M.AND arg => logical_ud arg
  237.        | M.OR arg  => logical_ud arg
  238.        | M.XOR arg => logical_ud arg
  239.  
  240.        | M.ADD(arg as (rd,_,rs))  => 
  241.          (case (reg_rep rd, rs)
  242.            of (Reg' 0, RegOp rs') => if reg_eq(rs',M.limitReg)
  243.                          then (allR, allR)  
  244.                          else arith_ud arg
  245.         | _ => let val (u,d) = arith_ud arg
  246.                 in if is_allocR rd then (u, RId.mem::d) else (u,d)
  247.                end)
  248.        | M.ADDU arg => arith_ud arg
  249.        | M.SUB arg  => arith3_ud arg
  250.             
  251.        | M.MFLO rd => ([RId.LO], RId.reg rd)
  252.        | M.MFHI rd => ([RId.HI], RId.reg rd)
  253.  
  254.        | M.MULT arg => mult_ud arg
  255.        | M.DIV arg  => mult_ud arg
  256.  
  257.        | M.NEG_DOUBLE(fd,fs)     => (RId.fregd fs, RId.fregd fd)
  258.        | M.ABS_DOUBLE(fd,fs)     => (RId.fregd fs, RId.fregd fd)
  259.        | M.MUL_DOUBLE arg         => double_float_ud arg
  260.        | M.DIV_DOUBLE arg         => double_float_ud arg
  261.        | M.ADD_DOUBLE arg         => double_float_ud arg 
  262.        | M.SUB_DOUBLE arg         => double_float_ud arg 
  263.        | M.CVTI2D(dst,src)      => (RId.freg src,RId.fregd dst)
  264.        | M.MTC1(src,dst)         => (RId.reg src,RId.freg dst)
  265.          
  266.        | M.MOV_DOUBLE(fd,fs) =>    (RId.fregd fs, RId.fregd fd)
  267.  
  268.        | M.LBU arg        => load_ud arg
  269.        | M.LW arg         => load_ud arg
  270.        | M.LWC1 arg       => load_ud arg
  271.        | M.SB arg         => store_ud arg
  272.        | M.SW arg         => store_ud arg
  273.        | M.SWC1 arg      => store_ud arg
  274.  
  275.        | M.LUI(rd,_)      => ([], RId.reg rd)
  276.                
  277.        | M.SLL(rd,rt,_)   => (RId.reg rt, RId.reg rd)
  278.        | M.SRA(rd,rt,_)   => (RId.reg rt, RId.reg rd)
  279.        | M.SLLV arg       => logical3_ud arg
  280.        | M.SRAV arg       => logical3_ud arg
  281.  
  282.  
  283.   fun usesReg (r,I) = let val (ul,_) = rUseDef I
  284.               val [rR] = RId.anyreg r
  285.               in exists (fn u => u = rR) ul
  286.               end
  287.  
  288.   fun mayNeedNop (M.LBU _)        = 1
  289.     | mayNeedNop (M.LW _)         = 1
  290.     | mayNeedNop (M.LWC1 _)       = 1
  291.     | mayNeedNop (M.SLT_DOUBLE _) = 1
  292.     | mayNeedNop (M.SEQ_DOUBLE _) = 1
  293.     | mayNeedNop (M.MFLO _)       = 2
  294.     | mayNeedNop (M.MFHI _)       = 2
  295.     | mayNeedNop (M.BLTZAL _)      = 1
  296.     | mayNeedNop (M.MTC1 _)      = 1
  297.     | mayNeedNop (M.BEQ _)      = 1
  298.     | mayNeedNop (M.BCOP1 _)      = 1
  299.     | mayNeedNop (M.JUMP _)      = 1
  300.     | mayNeedNop _           = 0
  301.  
  302.   fun needsNop(MULT _, MFLO _ :: _)  = 2
  303.     | needsNop(MULT _, _::MFLO _::_) = 1 
  304.     | needsNop(MULT _, MFHI _::_)    = 2 
  305.     | needsNop(MULT _, _::MFHI _::_) = 1 
  306.     | needsNop(next,prev::rest) =
  307.       (case prev
  308.     of M.LBU(rd,_,_)  => if usesReg(rd,next) then 1 else 0
  309.      | M.LW(rd,_,_)   => if usesReg(rd,next) then 1 else 0
  310.      | M.LWC1(fd,_,_) => if usesReg(fd,next) then 1 else 0
  311.      | M.SLT_DOUBLE _ => (case next of M.BCOP1 _ => 1 | _ => 0)
  312.      | M.SEQ_DOUBLE _ => (case next of M.BCOP1 _ => 1 | _ => 0)
  313.      | M.MTC1(_,fs)   => if usesReg(fs,next) then 1 else 0
  314.      | M.BLTZAL _ => (case instrKind next of IK_JUMP => 1 | _ => 0)
  315.      | _          => (case (instrKind next,instrKind prev) 
  316.                 of (IK_JUMP,IK_JUMP) => 1
  317.                  | _  => 0))
  318.     | needsNop _ = 0
  319.  
  320.   (* R2000 latencies *)
  321.   fun latency (M.LW _)         = 2
  322.     | latency (M.LWC1 _)     = 2
  323.     | latency (M.LBU _)        = 2
  324.     | latency (M.MULT _)    = 11
  325.     | latency (M.DIV _)        = 36
  326.     | latency (M.JUMP _)    = 2
  327.     | latency (M.BEQ _)        = 2
  328.     | latency (M.BCOP1 _)    = 2
  329.     | latency (M.SEQ_DOUBLE _)    = 2
  330.     | latency (M.SLT_DOUBLE _)     = 2
  331.     | latency (M.ADD_DOUBLE _)  = 2
  332.     | latency (M.MUL_DOUBLE _)  = 5
  333.     | latency (M.DIV_DOUBLE _)    = 19
  334.     | latency _            = 1
  335.  
  336. end 
  337. end
  338.